using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CoroutineRunner : MonoBehaviour
{
	private List<Action> inMineThreadActions = new List<Action>();

	private static CoroutineRunner _instance;

	public static CoroutineRunner Instance
	{
		get
		{
			if (_instance == null)
			{
				try
				{
					GameObject gameObject = new GameObject("CoroutineRunner");
					_instance = gameObject.AddComponent<CoroutineRunner>();
					UnityEngine.Object.DontDestroyOnLoad(gameObject);
				}
				catch (Exception ex)
				{
					Debug.LogError("[Rilisoft] CoroutineRunner: Instance exception: " + ex);
				}
			}
			return _instance;
		}
	}

	public static IEnumerator WaitForSeconds(float tm)
	{
		float startTime = Time.realtimeSinceStartup;
		do
		{
			yield return null;
		}
		while (Time.realtimeSinceStartup - startTime < tm);
	}

	public static IEnumerator WaitForSecondsActionEveryNFrames(float tm, Action action, int everyNFrames)
	{
		float startTime = Time.realtimeSinceStartup;
		int i = 0;
		do
		{
			yield return null;
			i++;
			if (i % everyNFrames == 0 && action != null)
			{
				action();
			}
		}
		while (Time.realtimeSinceStartup - startTime < tm);
	}

	public static Coroutine Invoke(float time, Action onActiveAction)
	{
		return Instance.StartCoroutine(Instance.InvokeAction(time, onActiveAction));
	}

	protected IEnumerator InvokeAction(float time, Action onActiveAction)
	{
		yield return new WaitForSeconds(time);
		if (onActiveAction != null)
		{
			onActiveAction();
		}
	}

	public static void WaitUntil(Func<bool> func, Action onActiveAction)
	{
		Instance.StartCoroutine(Instance.WaitUntilCoroutine(func, onActiveAction));
	}

	public static void CallInMainThread(Action action)
	{
		Instance.inMineThreadActions.Add(action);
	}

	private void Update()
	{
		if (inMineThreadActions.Count <= 0)
		{
			return;
		}
		for (int i = 0; i < inMineThreadActions.Count; i++)
		{
			try
			{
				inMineThreadActions[i]();
			}
			catch (Exception)
			{
			}
		}
		inMineThreadActions.Clear();
	}

	private IEnumerator WaitUntilCoroutine(Func<bool> func, Action onActiveAction)
	{
		yield return new WaitUntil(func);
		if (onActiveAction != null)
		{
			onActiveAction();
		}
	}
}
